/*LICENSE_BEGIN
 * ******************************************************************
 * Copyright 2006 by the Dainamite Robocup-Team at the
 * DAI-Labor, TU-Berlin (www.dai-labor.de)
 * 
 * Members of Dainamite are:
 * Holger Endert
 * Robert Wetzker
 * Thomas Karbe
 * Axel Heßler
 * Philippe Bütter
 * Felix Brossmann
 * 
 * Licensed under the GNU GPL (General Public License) Free Software 
 * License, Version 2. You may use this file only in compliance with 
 * the License. You may obtain a copy of the License at:
 * 
 * http://www.fsf.org/licensing/licenses/gpl.txt
 * ******************************************************************
LICENSE_END*/
package robocup.component.tactics;

import java.util.Arrays;

import robocup.component.SConf;
import robocup.component.ControllerNumbers.PLAY_MODE;
import robocup.component.actionfactories.TurnNeckActionFactory;

/**
 * This state implements most parts of the behaviour of the goalie. 
 * Especially his positioning and when to catch the ball.
 */
public class GoalkeeperState extends AbstractState {

	/**
	 * @param parent -
	 *            the StateEvaluation (parent) object
	 */
	public GoalkeeperState(StateEvaluation parent) {

		super(parent);
		this.state = STATES.GOALKEEPER;
	}

	/**
	 * PreCondition is canCatch() and playMode PlayOn!
	 */
	@Override
	public boolean preCondition() {
		if (getWorld().getPlayMode() == PLAY_MODE.FREE_KICK_OWN
				&& checkPlayerHasBall()) {
			return false;
		}
		return (getWorld().isGoalie() && checkPlayMode());
	}

	/**
	 * Most important action of goale => Prob 1.
	 */
	@Override
	protected double successProbability() {

		return 1;
	}

	/**
	 * Most important action of goale => Benefit 1.
	 */
	@Override
	protected double successBenefit() {

		if (getWorld().getBallRef().getAge(getWorld().getBodyCycle()) > 5) {
			return 0;
		}
		return getProphet().getGoalieActionBenefit();
	}

	public void setSubStateString() {
		subStateString = getProphet().getGoalieSubStateString();
	}

	@Override
	public void calculateMainAction() {
		mainAction = getProphet().getBestGoalieAction();
	}

	@Override
	public void calculateTurnNeckAction() {
		if (getProphet().getInterceptionTime() == 0) {
			turnNeckAction = TurnNeckActionFactory
					.watchPoint(getWorld().getSelfRef(), getProphet()
							.getPlayersThatCanKick().size() == 0 ? getWorld()
							.getBallRef().getFuturePos(1,
									SConf.getInstance().BALL_DECAY)
							: getProphet().getPlayersThatCanKick().getFirst()
									.getPosition());
		} else {
			turnNeckAction = TurnNeckActionFactory.watchPoint(getWorld()
					.getSelfRef(), getWorld().getBallRef().getFuturePos(1,
					SConf.getInstance().BALL_DECAY));
		}
		if (turnNeckAction != null) {
			return;
		}
		if (this
				.getWorld()
				.getBallRef()
				.getAge(
						this.getWorld().getBodyCycle(),
						robocup.component.worldobjects.Ball.UPDATE_MODE.SEEN_WITHOUT_SPEED) > 2) {
			turnNeckAction = TurnNeckActionFactory.getAction(this.getWorld(),
					state, mainAction, viewModeAction, this
							.getWorld().getBallRef());
			return;
		}

		double[] lookTo = new double[23];
		Arrays.fill(lookTo, -1);
		lookTo[22] = 1;
		turnNeckAction = getWorld().canKick()
				|| getWorld().getBallRef().getAge(getWorld().getBodyCycle()) > 5 ? TurnNeckActionFactory
				.getAction(getWorld(), STATES.GOALKEEPER, mainAction,
						viewModeAction)
				: TurnNeckActionFactory.getAction(getWorld(),
						STATES.GOALKEEPER, mainAction, viewModeAction,
						lookTo);
	}

}
